﻿using B.Z.Inventory.API.Read.Application.Command;
using B.Z.Inventory.API.Read.DTO;
using B.Z.Inventory.ErrorCode;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace B.Z.Inventory.API.Read.Controllers
{
    /// <summary>
    /// 库存统计-控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class StatisticsController : ControllerBase
    {
        private readonly IMediator mediator;
        private readonly IHubContext<InventoryReadHub> hubContext;

        public StatisticsController(IMediator mediator, IHubContext<InventoryReadHub> hubContext)
        {
            this.mediator = mediator;
            this.hubContext = hubContext;
        }

        /// <summary>
        /// 盘点货品数量所占库存比率
        /// </summary>
        /// <param name="storeId">仓库ID（可选）</param>
        /// <param name="category">商品分类（可选）</param>
        /// <param name="topCount">返回条数（默认10）</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<GoodsInventoryNumberDto>> GetGoodsPercentageNumber(int? storeId = null, string? category = null, int topCount = 10) 
        {
            var request = new GoodsInventoryNumberCommand 
            { 
                StoreId = storeId, 
                Category = category, 
                TopCount = topCount 
            };
            var result = await mediator.Send(request);
            
            // 通过SignalR推送实时数据
            if (result.Code == APIEnums.ok && result.Data != null)
            {
                await hubContext.Clients.All.SendAsync("ReceiveInventoryQuantityRatio", result.Data);
            }
            
            return result;
        }

        /// <summary>
        /// 获取库存金额占比统计
        /// </summary>
        /// <param name="storeId">仓库ID（可选）</param>
        /// <param name="category">商品分类（可选）</param>
        /// <param name="topCount">返回条数（默认10）</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<InventoryAmountRatioDto>> GetInventoryAmountRatio(int? storeId = null, string? category = null, int topCount = 10)
        {
            var request = new InventoryAmountRatioCommand 
            { 
                StoreId = storeId, 
                Category = category, 
                TopCount = topCount 
            };
            var result = await mediator.Send(request);
            
            // 通过SignalR推送实时数据
            if (result.Code == APIEnums.ok && result.Data != null)
            {
                await hubContext.Clients.All.SendAsync("ReceiveInventoryAmountRatio", result.Data);
            }
            
            return result;
        }

        /// <summary>
        /// 获取出入库排名统计
        /// </summary>
        /// <param name="isInbound">是否入库排名（true：入库，false：出库）</param>
        /// <param name="startDate">开始时间</param>
        /// <param name="endDate">结束时间</param>
        /// <param name="storeId">仓库ID（可选）</param>
        /// <param name="topCount">返回条数（默认10）</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<InOutboundRankingDto>> GetInOutboundRanking(bool isInbound, DateTime? startDate = null, DateTime? endDate = null, int? storeId = null, int topCount = 10)
        {
            var request = new InOutboundRankingCommand
            {
                IsInbound = isInbound,
                StartDate = startDate,
                EndDate = endDate,
                StoreId = storeId,
                TopCount = topCount
            };
            var result = await mediator.Send(request);
            
            // 通过SignalR推送实时数据
            if (result.Code == APIEnums.ok && result.Data != null)
            {
                await hubContext.Clients.All.SendAsync("ReceiveInOutboundRanking", result.Data);
            }
            
            return result;
        }

        /// <summary>
        /// 获取出入库统计数据
        /// </summary>
        /// <param name="startDate">开始时间</param>
        /// <param name="endDate">结束时间</param>
        /// <param name="storeId">仓库ID（可选）</param>
        /// <param name="goodsId">商品ID（可选）</param>
        /// <param name="includeDailyDetails">是否包含每日明细（默认true）</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<InOutboundStatisticsDto>> GetInOutboundStatistics(DateTime? startDate = null, DateTime? endDate = null, int? storeId = null, int? goodsId = null, bool includeDailyDetails = true)
        {
            var request = new InOutboundStatisticsCommand
            {
                StartDate = startDate,
                EndDate = endDate,
                StoreId = storeId,
                GoodsId = goodsId,
                IncludeDailyDetails = includeDailyDetails
            };
            var result = await mediator.Send(request);
            
            // 通过SignalR推送实时数据
            if (result.Code == APIEnums.ok && result.Data != null)
            {
                await hubContext.Clients.All.SendAsync("ReceiveInOutboundStatistics", result.Data);
            }
            
            return result;
        }

        /// <summary>
        /// 获取库存预警信息
        /// </summary>
        /// <param name="storeId">仓库ID（可选）</param>
        /// <param name="alertLevel">预警级别（1:低库存，2:安全库存，3:缺货，null:全部）</param>
        /// <param name="category">商品分类（可选）</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<LowStockAlertDto>> GetLowStockAlert(int? storeId = null, int? alertLevel = null, string? category = null)
        {
            var request = new LowStockAlertCommand
            {
                StoreId = storeId,
                AlertLevel = alertLevel,
                Category = category
            };
            var result = await mediator.Send(request);
            
            // 通过SignalR推送预警信息
            if (result.Code == APIEnums.ok && result.Data != null && result.Data.TotalAlertCount > 0)
            {
                await hubContext.Clients.All.SendAsync("ReceiveLowStockAlert", result.Data);
            }
            
            return result;
        }

        /// <summary>
        /// 发送入库成功消息
        /// </summary>
        /// <param name="goodsName">商品名称</param>
        /// <param name="quantity">入库数量</param>
        /// <param name="operatorName">操作人员</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<APIResult<bool>> SendInboundSuccessMessage(string goodsName, int quantity, string operatorName)
        {
            var result = new APIResult<bool> { Code = APIEnums.ok, Data = true };
            
            try
            {
                var message = new SystemMessageDto
                {
                    MessageId = Guid.NewGuid().ToString(),
                    MessageType = "InboundSuccess",
                    Title = "入库成功",
                    Content = $"商品【{goodsName}】入库成功，数量：{quantity}",
                    Quantity = quantity,
                    OperatorName = operatorName,
                    MessageTime = DateTime.Now,
                    Level = "success"
                };

                await hubContext.Clients.All.SendAsync("ReceiveInboundSuccess", message);
                
                result.Message = "入库成功消息已发送";
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.fail;
                result.Message = $"发送入库成功消息失败：{ex.Message}";
                result.Data = false;
            }
            
            return result;
        }

        /// <summary>
        /// 发送出库成功消息
        /// </summary>
        /// <param name="goodsName">商品名称</param>
        /// <param name="quantity">出库数量</param>
        /// <param name="operatorName">操作人员</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<APIResult<bool>> SendOutboundSuccessMessage(string goodsName, int quantity, string operatorName)
        {
            var result = new APIResult<bool> { Code = APIEnums.ok, Data = true };
            
            try
            {
                var message = new SystemMessageDto
                {
                    MessageId = Guid.NewGuid().ToString(),
                    MessageType = "OutboundSuccess",
                    Title = "出库成功",
                    Content = $"商品【{goodsName}】出库成功，数量：{quantity}",
                    Quantity = quantity,
                    OperatorName = operatorName,
                    MessageTime = DateTime.Now,
                    Level = "success"
                };

                await hubContext.Clients.All.SendAsync("ReceiveOutboundSuccess", message);
                
                result.Message = "出库成功消息已发送";
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.fail;
                result.Message = $"发送出库成功消息失败：{ex.Message}";
                result.Data = false;
            }
            
            return result;
        }

        /// <summary>
        /// 获取综合仪表板数据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<object>> GetDashboardData()
        {
            var result = new APIResult<object> { Code = APIEnums.ok };
            
            try
            {
                // 并行获取各种统计数据
                var task1 = mediator.Send(new GoodsInventoryNumberCommand { TopCount = 5 });
                var task2 = mediator.Send(new InventoryAmountRatioCommand { TopCount = 5 });
                var task3 = mediator.Send(new InOutboundRankingCommand { IsInbound = true, TopCount = 5 });
                var task4 = mediator.Send(new InOutboundRankingCommand { IsInbound = false, TopCount = 5 });
                var task5 = mediator.Send(new LowStockAlertCommand());
                var task6 = mediator.Send(new InOutboundStatisticsCommand { StartDate = DateTime.Today.AddDays(-30), EndDate = DateTime.Today });

                await Task.WhenAll(task1, task2, task3, task4, task5, task6);

                var dashboardData = new
                {
                    InventoryQuantityRatio = task1.Result.Data,
                    InventoryAmountRatio = task2.Result.Data,
                    InboundRanking = task3.Result.Data,
                    OutboundRanking = task4.Result.Data,
                    LowStockAlert = task5.Result.Data,
                    RecentStatistics = task6.Result.Data,
                    LastUpdated = DateTime.Now
                };

                result.Data = dashboardData;
                
                // 通过SignalR推送综合数据
                await hubContext.Clients.All.SendAsync("ReceiveDashboardData", dashboardData);
                
                result.Message = "成功获取仪表板数据";
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.fail;
                result.Message = $"获取仪表板数据失败：{ex.Message}";
            }
            
            return result;
        }
    }
}
